package com.yunc.common.web.exception;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.yunc.common.core.result.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.Set;

/**
 * 全局系统异常处理
 **/
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    @ExceptionHandler(IllegalArgumentException.class)
    public R handleIllegalArgumentException(IllegalArgumentException e) {
        return R.error(e.getMessage());
    }

    @ExceptionHandler(JsonProcessingException.class)
    public R handleJsonProcessingException(JsonProcessingException e) {
        return R.error(e.getMessage());
    }

    @ExceptionHandler(UcException.class)
    public R handleUcException(UcException e) {
        if (e.getResultCode() != null) {
            return R.error(e.getMessage());
        }
        return R.error(e.getMessage());
    }

    @ExceptionHandler(SecurityException.class)
    public R handleSecurityException(SecurityException e) {
        if (e.getResultCode() != null) {
            return R.error(e.getMessage());
        }
        return R.error(e.getMessage());
    }

    /**
     * 数据校验异常
     */
    @ExceptionHandler(BindException.class)
    public R handleBindException(BindException e) {
        BindingResult bindingResult = e.getBindingResult();
        // getFieldError():随机返回一个对象属性的异常信息。如果要一次性返回所有对象属性异常信息，则调用ex.getAllErrors()
        FieldError fieldError = bindingResult.getFieldError();
        return R.error(fieldError.getDefaultMessage());
    }

    /**
     * 数据校验异常
     */
    @ExceptionHandler(ConstraintViolationException.class)
    public R handleBindException(ConstraintViolationException e) {
        Set<ConstraintViolation<?>> constraintViolations = e.getConstraintViolations();
        StringBuilder sb = new StringBuilder();
        for (ConstraintViolation<?> violation : constraintViolations) {
            sb.append(violation.getMessage());
        }
        return R.error(sb.toString());
    }

    /**
     * 数据校验异常
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public R handleBindException(MethodArgumentNotValidException e) {
        // ex.getFieldError():随机返回一个对象属性的异常信息。如果要一次性返回所有对象属性异常信息，则调用ex.getAllErrors()
        BindingResult bindingResult = e.getBindingResult();
        FieldError fieldError = bindingResult.getFieldError();
        /*StringBuilder sb = new StringBuilder();
        sb.append(fieldError.getField())
                .append("=[")
                .append(fieldError.getRejectedValue())
                .append("]")
                .append(fieldError.getDefaultMessage());*/
        return R.error(fieldError.getDefaultMessage());
    }
}
